﻿using System;
using GeoAPI.Geometries;

namespace NetTopologySuite.Operation.Distance3D
{
	public class AxisPlaneCoordinateSequence : ICoordinateSequence, ICloneable
	{
		public static ICoordinateSequence ProjectToXY(ICoordinateSequence seq)
		{
			return new AxisPlaneCoordinateSequence(seq, AxisPlaneCoordinateSequence.XYIndex);
		}

		public static ICoordinateSequence ProjectToXZ(ICoordinateSequence seq)
		{
			return new AxisPlaneCoordinateSequence(seq, AxisPlaneCoordinateSequence.XZIndex);
		}

		public static ICoordinateSequence ProjectToYZ(ICoordinateSequence seq)
		{
			return new AxisPlaneCoordinateSequence(seq, AxisPlaneCoordinateSequence.YZIndex);
		}

		private AxisPlaneCoordinateSequence(ICoordinateSequence seq, Ordinate[] indexMap)
		{
			this._seq = seq;
			this._indexMap = indexMap;
		}

		public int Dimension
		{
			get
			{
				return 2;
			}
		}

		public Ordinates Ordinates
		{
			get
			{
				return this._seq.Ordinates;
			}
		}

		public Coordinate GetCoordinate(int i)
		{
			return this.GetCoordinateCopy(i);
		}

		public Coordinate GetCoordinateCopy(int i)
		{
			return new Coordinate(this.GetX(i), this.GetY(i), this.GetZ(i));
		}

		public void GetCoordinate(int index, Coordinate coord)
		{
			coord.X = this.GetOrdinate(index, Ordinate.X);
			coord.Y = this.GetOrdinate(index, Ordinate.Y);
			coord.Z = this.GetOrdinate(index, Ordinate.Z);
		}

		public double GetX(int index)
		{
			return this.GetOrdinate(index, Ordinate.X);
		}

		public double GetY(int index)
		{
			return this.GetOrdinate(index, Ordinate.Y);
		}

		public double GetZ(int index)
		{
			return this.GetOrdinate(index, Ordinate.Z);
		}

		public double GetOrdinate(int index, Ordinate ordinateIndex)
		{
			if (ordinateIndex > Ordinate.Y)
			{
				return 0.0;
			}
			return this._seq.GetOrdinate(index, this._indexMap[(int)ordinateIndex]);
		}

		public int Count
		{
			get
			{
				return this._seq.Count;
			}
		}

		public void SetOrdinate(int index, Ordinate ordinateIndex, double value)
		{
			throw new NotSupportedException();
		}

		public Coordinate[] ToCoordinateArray()
		{
			throw new NotSupportedException();
		}

		public Envelope ExpandEnvelope(Envelope env)
		{
			throw new NotSupportedException();
		}

		public object Clone()
		{
			throw new NotSupportedException();
		}

		public ICoordinateSequence Reversed()
		{
			throw new NotSupportedException();
		}

		private static readonly Ordinate[] XYIndex = new Ordinate[]
		{
			Ordinate.X,
			Ordinate.Y
		};

		private static readonly Ordinate[] XZIndex = new Ordinate[]
		{
			Ordinate.X,
			Ordinate.Z
		};

		private static readonly Ordinate[] YZIndex = new Ordinate[]
		{
			Ordinate.Y,
			Ordinate.Z
		};

		private readonly ICoordinateSequence _seq;

		private readonly Ordinate[] _indexMap;
	}
}
